//! 日志级别集成测试
//!
//! 测试 FR1: 系统支持 6 个日志级别：TRACE、DEBUG、INFO、WARN、ERROR、FATAL
//! 测试 AC-2.1.1 ~ AC-2.1.5

mod common;

use log4r::{Level, ParseLevelError};
use std::str::FromStr;

/// [P0] 测试日志级别枚举定义 (AC-2.1.1)
/// Level 枚举包含 TRACE、DEBUG、INFO、WARN、ERROR、FATAL 六个变体
#[test]
fn test_level_enum_exists() {
    // GIVEN: log4r 模块已导入
    // WHEN: 访问 Level 枚举
    // THEN: 应包含 6 个级别，值从 0 到 5

    assert_eq!(Level::Trace as u8, 0);
    assert_eq!(Level::Debug as u8, 1);
    assert_eq!(Level::Info as u8, 2);
    assert_eq!(Level::Warn as u8, 3);
    assert_eq!(Level::Error as u8, 4);
    assert_eq!(Level::Fatal as u8, 5);
}

/// [P0] 测试级别比较：TRACE < DEBUG < INFO < WARN < ERROR < FATAL (AC-2.1.2)
/// Level 实现 Ord trait，级别从低到高排序
#[test]
fn test_level_ordering() {
    // GIVEN: 所有日志级别
    // WHEN: 比较级别大小
    // THEN: TRACE < DEBUG < INFO < WARN < ERROR < FATAL

    assert!(Level::Trace < Level::Debug);
    assert!(Level::Debug < Level::Info);
    assert!(Level::Info < Level::Warn);
    assert!(Level::Warn < Level::Error);
    assert!(Level::Error < Level::Fatal);

    // 测试相等性
    assert_eq!(Level::Info, Level::Info);
    assert_ne!(Level::Info, Level::Debug);
}

/// [P0] 测试级别显示格式 (AC-2.1.3)
/// Level 实现 Display trait，输出大写级别名称
#[test]
fn test_level_display() {
    // GIVEN: Level 枚举值
    // WHEN: 转换为字符串
    // THEN: 应返回大写格式

    assert_eq!(Level::Trace.to_string(), "TRACE");
    assert_eq!(Level::Debug.to_string(), "DEBUG");
    assert_eq!(Level::Info.to_string(), "INFO");
    assert_eq!(Level::Warn.to_string(), "WARN");
    assert_eq!(Level::Error.to_string(), "ERROR");
    assert_eq!(Level::Fatal.to_string(), "FATAL");
}

/// [P0] 测试级别字符串转换 (AC-2.1.4)
/// Level 实现 FromStr trait，支持大小写不敏感解析
#[test]
fn test_level_from_str() {
    // GIVEN: 级别字符串
    // WHEN: 解析为 Level 枚举
    // THEN: 应正确转换（大小写不敏感）

    // 小写
    assert_eq!(Level::from_str("trace"), Ok(Level::Trace));
    assert_eq!(Level::from_str("debug"), Ok(Level::Debug));
    assert_eq!(Level::from_str("info"), Ok(Level::Info));
    assert_eq!(Level::from_str("warn"), Ok(Level::Warn));
    assert_eq!(Level::from_str("error"), Ok(Level::Error));
    assert_eq!(Level::from_str("fatal"), Ok(Level::Fatal));

    // 大写
    assert_eq!(Level::from_str("TRACE"), Ok(Level::Trace));
    assert_eq!(Level::from_str("DEBUG"), Ok(Level::Debug));
    assert_eq!(Level::from_str("INFO"), Ok(Level::Info));
    assert_eq!(Level::from_str("WARN"), Ok(Level::Warn));
    assert_eq!(Level::from_str("ERROR"), Ok(Level::Error));
    assert_eq!(Level::from_str("FATAL"), Ok(Level::Fatal));

    // 混合大小写
    assert_eq!(Level::from_str("Trace"), Ok(Level::Trace));
    assert_eq!(Level::from_str("DeBuG"), Ok(Level::Debug));
    assert_eq!(Level::from_str("iNfO"), Ok(Level::Info));
}

/// [P1] 测试无效级别字符串 (AC-2.1.4)
#[test]
fn test_level_from_str_invalid() {
    // GIVEN: 无效的级别字符串
    // WHEN: 尝试解析
    // THEN: 应返回错误

    assert!(Level::from_str("INVALID").is_err());
    assert!(Level::from_str("").is_err());
    assert!(Level::from_str("warning").is_err()); // 不是 WARN
    assert!(Level::from_str("information").is_err()); // 不是 INFO
}

/// [P0] 测试 Level 与 tracing::Level 转换 (AC-2.1.5)
/// Level 可以与 tracing::Level 相互转换（FATAL 转换为 None）
#[test]
fn test_level_to_tracing() {
    // GIVEN: log4r Level 枚举值
    // WHEN: 转换为 tracing::Level
    // THEN: 应正确映射，FATAL 返回 None

    assert_eq!(Level::Trace.to_tracing_level(), Some(tracing::Level::TRACE));
    assert_eq!(Level::Debug.to_tracing_level(), Some(tracing::Level::DEBUG));
    assert_eq!(Level::Info.to_tracing_level(), Some(tracing::Level::INFO));
    assert_eq!(Level::Warn.to_tracing_level(), Some(tracing::Level::WARN));
    assert_eq!(Level::Error.to_tracing_level(), Some(tracing::Level::ERROR));
    // FATAL 是 log4r 独有，tracing 没有对应级别
    assert_eq!(Level::Fatal.to_tracing_level(), None);
}

/// [P2] 测试 Level as_str 方法
#[test]
fn test_level_as_str() {
    // GIVEN: Level 枚举值
    // WHEN: 调用 as_str()
    // THEN: 应返回大写字符串

    assert_eq!(Level::Trace.as_str(), "TRACE");
    assert_eq!(Level::Debug.as_str(), "DEBUG");
    assert_eq!(Level::Info.as_str(), "INFO");
    assert_eq!(Level::Warn.as_str(), "WARN");
    assert_eq!(Level::Error.as_str(), "ERROR");
    assert_eq!(Level::Fatal.as_str(), "FATAL");
}

/// [P1] 测试级别过滤逻辑
#[test]
fn test_level_filter() {
    // GIVEN: 设置日志级别为 INFO
    // WHEN: 记录不同级别的日志
    // THEN: TRACE 和 DEBUG 应被过滤

    let filter_level = Level::Info;
    assert!(!Level::Trace.should_log(filter_level));
    assert!(!Level::Debug.should_log(filter_level));
    assert!(Level::Info.should_log(filter_level));
    assert!(Level::Warn.should_log(filter_level));
    assert!(Level::Error.should_log(filter_level));
    assert!(Level::Fatal.should_log(filter_level));
}

/// [P0] 测试 ParseLevelError 错误信息
#[test]
fn test_parse_level_error() {
    // GIVEN: 无效的级别字符串
    // WHEN: 解析失败
    // THEN: 错误应包含无效输入

    let result = Level::from_str("invalid");
    assert!(result.is_err());

    let err = result.err().unwrap_or_else(|| ParseLevelError {
        invalid_input: String::new(),
    });
    assert_eq!(err.invalid_input, "invalid");
    assert!(err.to_string().contains("invalid"));
}

/// [P2] 测试 ParseLevelError 实现 std::error::Error
#[test]
fn test_parse_level_error_is_error() {
    // GIVEN: ParseLevelError
    // WHEN: 作为 std::error::Error 使用
    // THEN: 应正常工作

    let err = ParseLevelError {
        invalid_input: "test".to_string(),
    };

    // 验证实现了 Error trait
    let _: &dyn std::error::Error = &err;

    // 验证 Display 输出
    assert!(err.to_string().contains("test"));
}

/// [P2] 测试 Level 实现 Clone, Copy, Hash
#[test]
fn test_level_traits() {
    // GIVEN: Level 枚举值
    // WHEN: 使用 Clone, Copy, Hash
    // THEN: 应正常工作

    // Clone (Level 实现 Copy，但也应支持 Clone)
    fn assert_clone<T: Clone>() {}
    assert_clone::<Level>();

    let level = Level::Info;
    let cloned = level; // Copy
    assert_eq!(level, cloned);

    // Copy
    let copied = level;
    assert_eq!(level, copied);

    // Hash - 通过 HashSet 验证
    use std::collections::HashSet;
    let mut set = HashSet::new();
    set.insert(Level::Info);
    set.insert(Level::Debug);
    assert!(set.contains(&Level::Info));
    assert!(set.contains(&Level::Debug));
    assert!(!set.contains(&Level::Error));
}

/// [P2] 测试 Level 实现 Debug
#[test]
fn test_level_debug() {
    // GIVEN: Level 枚举值
    // WHEN: 使用 Debug 格式化
    // THEN: 应输出有意义的调试信息

    let debug_str = format!("{:?}", Level::Info);
    assert!(debug_str.contains("Info"));
}
